<?php

namespace ldl\mysql;
use ldl\mysql\LmysqlTable;
use ldl\mysql\LtableBase;
use Amp\Mysql\ResultSet;
//$DB=new DbManager();
/*
 *run sql from super Sql  ,dbManager  from global var
 * */
function stdObjectToArr(&$object){
	
	$object =  json_decode( json_encode( $object),true);
	return  $object;
}
class DbTable implements LmysqlTable,DbManFactory{
	protected $_pk="id";
	protected $_tableName;
	protected static $dbs;
	function __construct($tableInfo){
		if(is_array($tableInfo)) {
			isset($tableInfo['pk']) ? $this->_pk=$tableInfo['pk']:'' ;
			$this->_tableName=$tableInfo['table'] ;
		}else{
			$this->_tableName=$tableInfo;
		}
		if($this->db==null){
			$this->db = $this->getDb();
		}
	}
	
       //拿到执行Sql 的对像
    public  function getDb(){
        if(self::$dbs!=null){
            return self::$dbs;
	}
        self::$dbs = new DbManager();
        return self::$dbs;
    }

	function insert($data,$replace=false,$returnId=true){
		$sql= LtableBase::insert($this->_tableName,$data,$returnId,$replace);
		/*$re;
		\Amp\Loop::run(function() use($sql,&$re){
			$result =yield  $this->db->execute($sql);
			$re=$result;
		});*/
		$re=\Amp\Promise\wait($this->db->execute($sql));
		if($returnId){
			return $re->insertId();
		}
	}
	function update($data,$where){
		$sql=LtableBase::update($this->_tableName,$data,$where);
		/*$re;
		\Amp\Loop::run(function() use($sql,&$re){
		//下面的代码无法移到外面 
			// must in run(.....)
			$result =yield  $this->db->execute($sql);
	
			$re=$result;
	});*/
		$re=\Amp\Promise\wait($this->db->execute($sql));
		return $re->affectedRows();
	
	}
	function delete($where){
		$sql=LtableBase::delete($this->_tableName,$where);
	/*
		$re;
		\Amp\Loop::run(function() use($sql,&$re){
			$result =yield  $this->db->execute($sql);
			$re=$result;
		});*/
		$re=\Amp\Promise\wait($this->db->execute($sql));
		return $re->affectedRows();
	}
	function count($where,$start=0,$limit=0,$sort=''){
		$sql=$this->vollsql($where,$start,$limit,$sort);
		$sql="SELECT count(0) from ( $sql ) _" ;
		$a=$this->resultObjects($sql);
		$a=stdObjectToArr($a);
		return isset($a[0]) ? $a[0]['count(0)'] : 0; 
	}
	function exec($sql){
		return $this->resultObjects($sql);
	}
	function select($where,$start=0,$limit=0,$sort=''){
		$sql=$this->vollsql($where,$start,$limit,$sort);
		$re=$this->resultObjects($sql);
       /*
 *                 $res=	\Amp\run(function()use ($sql){
 *                         $promise=$this->db->execute($sql);
 *                         //var_dump($promise->fetchRows());
 *                 //var_dump($promise);
 *                 for ($rows = (yield $promise); $rows !== null; $rows = (yield $rows->next())) {
 *                 while (($row = (yield $rows->fetch())) !== null) {
 *                 //	var_dump($row); 
 *                 }
 * 
 *                         //var_dump(yield $rows->rowCount());
 *                 }
 *         $this->db->close();
 *                 return "c";
 *                 });
 */
		return stdObjectToArr($re);
	}

    protected function resultObjects($sql){
		$result;
		//$sql="select 1 as d";
		/*\Amp\Loop::run(function() use($sql,&$re){
			$result =yield $this->db->execute($sql);
			while(yield $result->advance(2)){
			$re[]=$result->getCurrent();
		 }
		});*/
		$re=\Amp\Promise\wait($this->db->execute($sql));
		while(\Amp\Promise\wait($re->advance(2))){
			$result[]=$re->getCurrent();
		}
		return $result;

	}
	/*
	 * 拿到完整的SQL 有LIMIT ORDER
	 * */
	protected function vollsql($where,$start=0,$limit=0,$sort=''){

			
		$sql=LtableBase::select($this->_tableName,$where);
		if(!empty($sort)){
			$sql.= " ".LtableBase::order($sort);
		}
		
		$lim=LtableBase::limit($start,$limit);
		$sql.=" ".$lim;

		return $sql;
	}
	/*
	 * query by many PrimayrKey
	 * */
	function fetchs($ids){
		$ql=LtableBase::field($this->_pk,$ids,'in');
		//echo "$ql \n444";exit;
		$ql=$this->select($ql);
		return $ql;
	}
	/**
	 * query by PrimaryKey
	 */
	function fetch($id){
		if(!is_array($id)){
			$id=array($this->_pk=>$id);
		}
		$re=$this->select($id);
		return isset($re[0]) ? $re[0]: array();
	}
	
}
interface DbManFactory{
	function getDb();
}
